﻿using System;
using System.ComponentModel;
#if TASKSUPPORT
using System.Threading.Tasks;
#endif
using MugenMvvmToolkit.Infrastructure;
using MugenMvvmToolkit.Interfaces;
using MugenMvvmToolkit.Interfaces.ViewModels;

namespace MugenMvvmToolkit.Models
{
    /// <summary>
    ///     Represents the method that handles the CollectionChanging event.
    /// </summary>
    /// <param name="sender">The object that raised the event.</param>
    /// <param name="e">Information about the event.</param>
    public delegate void NotifyCollectionChangingEventHandler(object sender, NotifyCollectionChangingEventArgs e);

    /// <summary>
    ///     Represents the delegate that will handle events raised when a <c>ICloseableViewModel</c> closing.
    /// </summary>
    /// <param name="viewModel">The specified view-model.</param>
    /// <param name="eventArgs">The specified arguments.</param>
    /// <param name="parameter">The specified parameter if any.</param>
    public delegate void ViewModelClosingDelegate(
        ICloseableViewModel viewModel, CancelEventArgs eventArgs, object parameter);

    /// <summary>
    ///     Represents the delegate that will handle events raised when a <c>ICloseableViewModel</c> closing.
    /// </summary>
    /// <param name="viewModel">The specified view-model.</param>
    /// <param name="parameter">The specified parameter if any.</param>
    public delegate void ViewModelClosedDelegate(ICloseableViewModel viewModel, object parameter);

    /// <summary>
    ///     Represents the delegate that will handle events raised when a <c>SelectedItem</c> property changed.
    /// </summary>
    /// <typeparam name="T">The type of model.</typeparam>
    /// <param name="oldValue">The specified old value.</param>
    /// <param name="newValue">The specified new value.</param>
    public delegate void SelectedItemChangedHandler<in T>(T oldValue, T newValue);

    /// <summary>
    ///     Represents the delegate to create view model.
    /// </summary>
    /// <typeparam name="T">The type of view-model.</typeparam>
    /// <param name="iocAdapter">The specified <see cref="IIocAdapter" />.</param>
    /// <returns>An instance of <see cref="IViewModel" />.</returns>
    public delegate T GetViewModelDelegate<out T>(IIocAdapter iocAdapter) where T : IViewModel;

#if TASKSUPPORT

    /// <summary>
    ///     Represents the delegate to initialize a new instance of the <see cref="CloseableViewModelFacade" /> class.
    /// </summary>
    public delegate CloseableViewModelFacade GetCloseableFacadeDelegate(
        ICloseableViewModel closeableViewModel, Action<string> propertyChangedCallback, Predicate<object> canExecutCloseCommand = null,
        Func<object, Task<bool>> onClosing = null, Action<object> onClosed = null);
#else
    /// <summary>
    ///     Represents the delegate to initialize a new instance of the <see cref="CloseableViewModelFacade" /> class.
    /// </summary>
    public delegate CloseableViewModelFacade GetCloseableFacadeDelegate(ICloseableViewModel closeableViewModel, Action<string> propertyChangedCallback, Predicate<object> canExecutCloseCommand = null,
        Func<object, IOperationResult<bool>> onClosing = null, Action<object> onClosed = null);
#endif

    /// <summary>
    /// Represents the delegate that used to invoke asynchronous action.
    /// </summary>
    /// <param name="exception">An instance of exception, if any. If during the execution an error occurred.</param>
    /// <param name="arg">An argument of delegate.</param>
    public delegate void ResultCallback<in T>(Exception exception, T arg);
}